﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Syntezator_mowy.Extras;
using System.Threading;
using System.Globalization;

using Microsoft.Speech.Recognition;
using Syntezator_mowy.SDDBD;
using Microsoft.Speech.Recognition.SrgsGrammar;
using System.IO;

namespace Syntezator_mowy.Sr
{
    public class Sr
    {
        private ParametryRozpoznawania parametry;
        private SpeechRecognitionEngine silnik;

        public Sr(ParametryRozpoznawania parametry, SpeechRecognitionEngine silnik)
        {
            this.parametry = parametry;
            this.silnik = silnik;
        }

        public void run()
        {
            Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
            Thread.CurrentThread.CurrentUICulture = new CultureInfo("pl-PL");

            this.silnik.SetInputToWaveFile(parametry.inputFile);
            RecognitionResult wynik = this.silnik.Recognize();

            using (StreamWriter writer = new StreamWriter(parametry.outputFile))
            {
                writer.Write(wynik.Text);
            }
            this.silnik.SetInputToNull();
        }

        static private SpeechRecognitionEngine inicjalizuSilnik(Jezyk jezyk)
        {
            switch (jezyk)
            {
                case Jezyk.POLSKI:
                    return new SpeechRecognitionEngine(new CultureInfo("pl-PL"));
                default:
                    return null;
            }
        }

        static public SpeechRecognitionEngine utworzGramatyke(Jezyk jezyk, Serwer bazaDanych)
        {
            SpeechRecognitionEngine engine = Sr.inicjalizuSilnik(jezyk);
            if (engine != null)
            {
                Thread.CurrentThread.CurrentCulture = new CultureInfo("pl-PL");
                Thread.CurrentThread.CurrentUICulture = new CultureInfo("pl-PL");
                #region GRAMATYKA ZWYKLA
                /*
                SrgsRule podmiot = new SrgsRule("podmiot");
                SrgsOneOf wartosciPodmiotu = new SrgsOneOf(bazaDanych.get(eDbElement.PODMIOT).ToArray());
                podmiot.Add(wartosciPodmiotu);
                SrgsRuleRef podmiotRef = new SrgsRuleRef(podmiot, "podmiotRef");

                SrgsRule przymiotnik = new SrgsRule("przymiotnik");
                SrgsOneOf wartosciPrzymiotnika = new SrgsOneOf(bazaDanych.get(eDbElement.PRZYMIOTNIK).ToArray());
                przymiotnik.Add(wartosciPrzymiotnika);
                SrgsRuleRef przymiotnikRef = new SrgsRuleRef(przymiotnik, "przymiotnikRef");

                SrgsRule podmiotZlozony = new SrgsRule("podmiot_zlozony");
                podmiotZlozony.Add(przymiotnikRef);
                podmiotZlozony.Add(podmiotRef);
                SrgsRuleRef podmiotZlozonyRef = new SrgsRuleRef(podmiotZlozony, "podmiotZlozonyRef");

                SrgsRule podmioty = new SrgsRule("podmioty");
                podmioty.Add(podmiotRef);
                podmioty.Add(podmiotZlozonyRef);
                SrgsRuleRef podmiotyRef = new SrgsRuleRef(podmioty, "podmiotyRef");

                SrgsRule orzeczenie = new SrgsRule("orzeczenie");
                SrgsOneOf wartosciOrzeczenia = new SrgsOneOf(bazaDanych.get(eDbElement.ORZECZENIE).ToArray());
                orzeczenie.Add(wartosciOrzeczenia);
                SrgsRuleRef orzeczenieRef = new SrgsRuleRef(orzeczenie, "orzeczenieRef");

                SrgsRule lacznik = new SrgsRule("lacznik");
                SrgsOneOf wartosciLacznika = new SrgsOneOf(bazaDanych.get(eDbElement.LACZNIK).ToArray());
                lacznik.Add(wartosciLacznika);
                SrgsRuleRef lacznikRef = new SrgsRuleRef(lacznik, "lacznikRef");

                // -- skladanie zdan

                SrgsRule plo = new SrgsRule("plo"); // podmiot  + lacznik + orzecznik przymiotnikowy
                plo.Add(podmiotRef);
                plo.Add(lacznikRef);
                plo.Add(przymiotnikRef);
                SrgsRuleRef ploRef = new SrgsRuleRef(plo, "ploRef");

                SrgsRule po = new SrgsRule("po"); // podmiot + orzeczenie
                po.Add(podmiotRef);
                po.Add(orzeczenieRef);
                SrgsRuleRef poRef = new SrgsRuleRef(po, "poRef");


                SrgsRule glowna = new SrgsRule("glowna");
                glowna.Scope = SrgsRuleScope.Public;

                glowna.Add(poRef);
                //glowna.Add(ploRef);

                SrgsDocument document = new SrgsDocument();
                document.Rules.Add(new SrgsRule[] { glowna, podmiot, podmiotZlozony, orzeczenie, przymiotnik, lacznik, po, plo });

                document.Root = glowna;

                Grammar g = new Grammar(document, "glowna");
                */
                #endregion
                #region GRAMATYKA MIASTA
                SrgsRule regulaMiasto = new SrgsRule("miasto");
                SrgsOneOf miasto = new SrgsOneOf(bazaDanych.get(eDbElement.MIASTO).ToArray());
                regulaMiasto.Add(miasto);

                SrgsRuleRef regulaMiastoRef = new SrgsRuleRef(regulaMiasto, "miastoRef");
                #endregion
                #region REGULA GLOWNA
                SrgsRule glowna = new SrgsRule("glowna");
                glowna.Scope = SrgsRuleScope.Public;

                glowna.Add(regulaMiastoRef);
                #endregion
                #region LADOWANIE REGUL
                SrgsDocument document = new SrgsDocument();
                document.Rules.Add(new SrgsRule[] { glowna, regulaMiasto, regulaMiasto });

                document.Root = glowna;

                Grammar g = new Grammar(document, "glowna");
                engine.LoadGrammar(g);
                #endregion
            }
            return engine;
        }
    }
}
